package com.tieland.xunda.common.sys;

import net.buffalo.service.ServiceRepository;
import net.buffalo.service.ServiceFactory;
import net.buffalo.service.NoSuchServiceException;
import net.buffalo.service.defaults.DefaultServiceFactory;
import net.buffalo.service.defaults.ServiceHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.ServletContext;
import java.util.*;
import java.io.InputStream;
import java.io.IOException;

import com.tieland.xunda.common.util.ConfUtil;

/**
 * User: qiukx
 * Date: 2008-7-29
 * Company: Freshpower
 * Description:
 */
public class PicoServiceRepository implements ServiceRepository {

    private static final Log LOG = LogFactory.getLog(PicoServiceRepository.class);

    private Map services = new HashMap();

    private ServiceFactory picoFactory;

    private static String BUFFALO_REPOSITORY = "buffalo-service";

    ServerContext serverContext = ServerContext.getInstance();

    public PicoServiceRepository(ServletContext ctx) {
        this(ctx, null);
    }

    public PicoServiceRepository(ServletContext ctx, String defaultProperties) {
        picoFactory = new PicoServiceFactory();

        initialize();
    }

    /**
     * Get the service via service id
     */
    public Object get(String serviceId) {
        Object serviceInstance = null;
        ServiceHolder s = (ServiceHolder) (services.get(serviceId));
        if (s == null) {
            throw new NoSuchServiceException(serviceId);
        }

        serviceInstance = picoFactory.getService(s.getServiceId(), s.getServiceName());

        return serviceInstance;
    }

    /**
     * register a service
     */
    public void register(String serviceId, String serviceName, String factoryId) {
        services.put(serviceId, new ServiceHolder(serviceId, serviceName, factoryId));
    }

    /**
     * register a service with default factory
     *
     * @param serviceId
     * @param serviceName
     */
    public void register(String serviceId, String serviceName) {
        register(serviceId, serviceName, ServiceFactory.DEFAULT);
    }

    /**
     * Register all services from a map
     *
     * @param services  map contains services(key - value)
     * @param factoryId factory id
     */
    public void registerAll(Map services, String factoryId) {
        Iterator iter = services.keySet().iterator();
        while (iter.hasNext()) {
            String name = (String) iter.next();
            String serviceImpl = (String) services.get(name);
            register(name, serviceImpl, factoryId);
        }
    }

    /**
     * initialize the repository.
     */
    private void initialize() {

        loadFromPico();

    }

    private void loadFromPico() {
        try {
            Properties buffaloServices = ConfUtil.load(BUFFALO_REPOSITORY);
            registerAll(buffaloServices, ServiceFactory.DEFAULT);
            if (!buffaloServices.isEmpty()) {
                Set serviceIds = buffaloServices.keySet();
                for (Iterator it = serviceIds.iterator(); it.hasNext();) {
                    String serviceId = (String) it.next();
                    String serviceName = (String) buffaloServices.get(serviceId);
                    Class clazz = Class.forName(serviceName);
                    serverContext.register(clazz);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
